#include "bev_net.h"

#include <stdio.h>

#include <string>

#include "utils.h"

BevNet::BevNet() noexcept {}

BevNet::~BevNet() { destory(); }

uint32_t BevNet::Run(DataBuf &data_frame) noexcept {
  printf("bevnet out_num = %d", out_buf_.num_of_buf);
  uint32_t Rval =
      SetInput(data_frame.kCat2491.first, data_frame.kCat2491.second,
               BevNet::InputType::CAT2491);
  if (Rval != 0U) {
    Print("Error encounted when handling kCat2491! size = %ld ...\n",
          data_frame.kCat2491.second);
    return 1;
  }
  Rval |= SetInput(data_frame.kCat2492.first, data_frame.kCat2492.second,
                   BevNet::InputType::CAT2492);
  if (Rval != 0U) {
    Print("Error encounted when handling kCat2492! size = %ld ...\n",
          data_frame.kCat2492.second);
    return 1;
  }

  Rval |= SetInput(data_frame.ring_matrix.first, data_frame.ring_matrix.second,
                   BevNet::InputType::RING_MATRIX);
  if (Rval != 0U) {
    Print("Error encounted when handling ring_matrix! size = %ld ...\n",
          data_frame.ring_matrix.second);
    return 1;
  }

  Rval |= SetInput(data_frame.ray_matrix.first, data_frame.ray_matrix.second,
                   BevNet::InputType::RAY_MATRIX);
  if (Rval != 0U) {
    Print("Error encounted when handling ray_matrix! size = %ld ...\n",
          data_frame.ray_matrix.second);
    return 1;
  }
  Rval |= SetInput(data_frame.lidar_data.first, data_frame.lidar_data.second,
                   BevNet::InputType::LIDAR_INPUT);
  if (Rval != 0U) {
    Print("Error encounted when handling lidar_data! size = %ld ...\n",
          data_frame.lidar_data.second);
    return 1;
  }
  Rval |= SetInput(data_frame.k2647.first, data_frame.k2647.second,
                   BevNet::InputType::GRID_SAMPLE);
  if (Rval != 0U) {
    Print("Error encounted when handling k2647! size = %ld ...\n",
          data_frame.k2647.second);
    return 1;
  }


  auto end_time_2 = CV_FlexidagTimestamp();
  Rval = RunBlock();
  auto end_time_3 = CV_FlexidagTimestamp();
  Print("Time of >> grid_sample << : %d us.\n", end_time_3 - end_time_2);

    // "OUT0": {
          // "box_0_cls,box_1_height,box_2_height,box_0_reg,box_0_vel,box_1_reg,box_3_cls,box_1_vel,box_1_cls,box_2_vel,box_3_reg,box_3_rot,box_3_vel": {
          //     "file": "combine_1_13_bub.out"
          // }
  // for (int i = 0; i < out_buf.num_of_buf; i++) {
  //   memcpy(ptr, out_buf.buf[i].pBuffer, 10*2);
  // }
}

void BevNet::test() {
  std::uint32_t Rval = 0;
  std::string ring_matrix_path = "./ring_matrix.bin";
  std::string ray_matrix_path = "./ray_matrix.bin";
  std::string lidar_input_path = "./lidar_input.bin";

  ImageOutbuffer image_out_buf_;
  char *grid_buffer;

  // todo
  //
  // step4.3 把第一段网络的运行结果送给第二段
  auto start_time_2 = CV_FlexidagTimestamp();
  Rval |= LoadInPutFile(ring_matrix_path, 2, &raw_, &ring_matrix);
  Rval |= LoadInPutFile(ray_matrix_path, 3, &raw_, &ray_matrix);
  Rval |= LoadInPutFile(lidar_input_path, 4, &raw_, &lidar_input);
  Rval = LoadInPutBuffer(image_out_buf_.cat2491, kCat2491, 0, &raw_, &cat2491);
  Rval |= LoadInPutBuffer(image_out_buf_.cat2492, kCat2492, 1, &raw_, &cat2492);
  Rval |= LoadInPutBuffer(grid_buffer, kGridSampleResSize, 5, &raw_,
                          &grid_sample_result);

  auto end_time_2 = CV_FlexidagTimestamp();

  // step4.4 跑第三段网络
  auto start_time_3 = CV_FlexidagTimestamp();
  Rval = AmbaCV_FlexidagRun(&handle_, &in_buf_, &out_buf_, &run_info_);
  auto end_time_3 = CV_FlexidagTimestamp();
  for (int i = 0; i < out_buf_.num_of_buf; i++) {
    Rval = AmbaCV_UtilityCmaMemInvalid(&out_buf_.buf[i]);
  }  
}

bool BevNet::SetInput(std::string const &path, InputType input_type) noexcept {
  return 0 == LoadInPutFile(path, input_type, &raw_, &inputblk_[input_type]);
}
bool BevNet::SetInput(char *input_buffer, std::uint32_t buffer_size,
                      InputType input_type) noexcept {
  return 0 == LoadInPutBuffer(input_buffer, buffer_size, input_type, &raw_,
                              &inputblk_[input_type]);
}

std::uint32_t BevNet::free_all_buffer() {
  std::uint32_t Rval = 0U;
  for (std::uint8_t i = 0; i < InputType::Count; ++i) {
    Rval |= AmbaCV_UtilityCmaMemFree(&inputblk_[i]);
  }

  // Rval |= AmbaCV_UtilityCmaMemFree(&cat2491);
  // Rval |= AmbaCV_UtilityCmaMemFree(&cat2492);
  // Rval |= AmbaCV_UtilityCmaMemFree(&lidar_input);
  // Rval |= AmbaCV_UtilityCmaMemFree(&ray_matrix);
  // Rval |= AmbaCV_UtilityCmaMemFree(&grid_sample_result);
  // Rval |= AmbaCV_UtilityCmaMemFree(&ring_matrix);

  if (Rval != 0U) {
    Print("BevNet free_all_buffer fail (0x%x)\n", Rval);
  }
  return Rval;
}
